/****************************************************************************
**
** Copyright (C) 2009-2010 Mist Poryvaev.
** All rights reserved.
** Contact: Mist Poryvaev (mist.poryvaev@gmail.com)
**
** This file is part of the RailWorm project.
**
****************************************************************************/

#ifndef HTMLGENIE_H
#define HTMLGENIE_H

#include <QtCore>
#include <QtNetwork>
#include <QtWebKit>
#include <QtGui>

struct HtmlGenericData {
	QString Tag;
	QString Content;
	QXmlStreamAttributes Attributes;
};
typedef QList<HtmlGenericData> HtmlGenericDataList;

struct HtmlFormData: public HtmlGenericData {
	QUrl Url;
	QStringList Pars;
	QString Method;
	QString Action;
};
typedef QList<HtmlFormData> HtmlFormDataList;

struct HtmlTableCellData {
	int Row;
	int Column;
	int ColSpan;
	QString Text;
};
typedef QList<HtmlTableCellData> HtmlTableCellDataList;

struct HtmlTableData: public HtmlGenericData {
	HtmlTableCellDataList Cells;
	int Rows;
	int Columns;
};
typedef QList<HtmlTableData> HtmlTableDataList;

struct HtmlLinkData: public HtmlGenericData {
	QUrl Url;
};
typedef QList<HtmlLinkData> HtmlLinkDataList;

struct HtmlOptionData {
	QString Value;
	QString Text;
};
typedef QList<HtmlOptionData> HtmlOptionDataList;

struct HtmlSelectorData: public HtmlGenericData {
	HtmlOptionDataList Options;
};
typedef QList<HtmlSelectorData> HtmlSelectorDataList;

struct HtmlInputData: public HtmlGenericData {
	QString Value;
	QString Text;
};
typedef QList<HtmlInputData> HtmlInputDataList;

struct HtmlScriptData: public HtmlGenericData {
	QString Language;
	QUrl Url;
	QString Code;
};
typedef QList<HtmlScriptData> HtmlScriptDataList;

// * - любое имя, главное, чтобы было это поле
struct HtmlElementPars {
	QString Name;
	QString Id;
	QString Class;
	QString Href;
	QString Content;
};

class HtmlResponse {
private:
	QString data;
	QUrl url;
	static QList<QWebElement> Generics(const QWebElement & _el, const HtmlElementPars & _pars = HtmlElementPars(), const QString & _tag = QString());
public:
	HtmlResponse(const QString & _data, const QUrl & _url = QUrl());
	~HtmlResponse();

	static HtmlGenericDataList Generics(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars(), const QString & _tag = QString());
	static HtmlTableDataList Tables(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlFormDataList Forms(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlLinkDataList Links(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlLinkDataList Images(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlSelectorDataList Selectors(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlInputDataList Inputs(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());
	static HtmlScriptDataList Scripts(const QString & _data, const HtmlElementPars & _pars = HtmlElementPars());

	HtmlGenericDataList Generics(const HtmlElementPars & _pars = HtmlElementPars(), const QString & _tag = QString());
	HtmlTableDataList Tables(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlFormDataList Forms(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlLinkDataList Links(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlLinkDataList Images(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlSelectorDataList Selectors(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlInputDataList Inputs(const HtmlElementPars & _pars = HtmlElementPars());
	HtmlScriptDataList Scripts(const HtmlElementPars & _pars = HtmlElementPars());

	const QString & Data();
	const QUrl & Url();
};

class HtmlGenie;
class HtmlResponseHandler: public QObject {
	Q_OBJECT
public:
	HtmlResponseHandler(HtmlGenie * _jinn, int _id, const QUrl & _url, const QByteArray & _content_type_header);
	~HtmlResponseHandler();
	void Cancel();
	void Request();
private slots:
	void PageFinished();
	void Timeout();
signals:
	void Response(HtmlResponse *, int, bool);
private:
//	QWebPage page;
	QNetworkReply * reply;
	int id;
	HtmlGenie * jinn;
	QNetworkRequest request;
};

class HtmlGenie : public QObject {
	Q_OBJECT
	friend class HtmlResponseHandler;
public:
	HtmlGenie(QObject * _parent = 0);
	~HtmlGenie();

	static QByteArray ContentTypeForm() { return "application/x-www-form-urlencoded"; }
	static QByteArray ContentTypeText() { return "text/html"; }
	static QNetworkAccessManager & NetMan();

	int Request(const QUrl & _url, const QByteArray & _content_type_header, QObject * Receiver, const char * Slot);
public slots:
	void Cancel();
private slots:
	void OnSslErrors(QNetworkReply * reply, const QList<QSslError> & errors);
private:
	static int id;
	static QNetworkAccessManager net_man;
	QMap<int, HtmlResponseHandler *> handlers;
};

#endif // HTMLGENIE_H
